/*****************************************************************************/ /* NEW GLX WIDGET DESCRIPTION */ /* Date: 01-03-94 */ /* Authors: Ed Millard */ /* Chris Carlson */ /* Michael Gold */ /* Glenn Shute */ /*****************************************************************************/ This directory contains source for another new version of the SGI GLX mixed mode Xt widget (GlxDraw) and the GLX mixed mode Motif widget (GlxMDraw). The Motif widget is identical to the Xt version except with the addition of the Primitive base class and the Motif interface. These widgets, like their predecessor GlxDraw and GlxMDraw widgets, allows the use of GL within X windows with Xt and Motif applications. This new version has now been ported to OpenGL as well. Compile options select GL or OpenGL versions of the widget and the overlay test program. This version also allows switching between single and double buffering in the GL window by using XtSetValues. Its intent is to reduce the application programming required to use single and double buffer in a mixed mode application. The OpenGL version has not been extensively tested but appears basically functional on: XZ Elan Extereme There are known problems with the OpenGL version on RealityEngine. This is being investigated. Use at your own risk, but I would be interested in hearing suggestions and complaints. Send these to: millard@sgi.com Some work has been done to add support for a switch to stereo mode inside the widget. This is not implemented under GL and is not working under OpenGL yet (hopefully optional stereo support will be added in the next release of this widget. OpenGL stereo in the widget depends on stereo support in OpenGL which is not available for the most part yet). REQUIREMENTS ------------ These widgets should work under: X11R4 Motif 1.1 IRIX 4.0.x X11R5 Motif 1.2 IRIX 5.x The OpenGL version will only work on IRIX 5.1+ on platforms which support OpenGL. DEMO MAKE --------- Run make in this directory to rebuild the library libsgiw.a, containing both the GlxDraw and GlxMDraw widgets. By default the flag -DUSE_GL is set so you will get the GL version of the widget. There are option lines in the Makefile to switch to the OpenGL version. You need to comment out two lines and uncomment the other two lines to switch between GL and OpenGL. APPLICATION MAKE ---------------- To use this new widget you must include the "GlxDraw.h" (or "GlxMDraw.h" for Motif) from this directory and not the one in /usr/include/X11/Xirisw. You must link with GlxDraw.o or GlxMDraw.o (for Xt version or Motif version respectively) or the libsgiw.a library from this directory instead of libXirisw.a. The objects or the archive should be placed ahead of IRIX archives or DSO's like -lGL or -lgl. In particular on IRIX 5 -lGL or -lgl may pull in /usr/lib/Xirisw if they are referenced before GlxDraw.o, GlxMDraw.o or libsgiw.a. USAGE ----- The example code below is provided to demonstrate how to create a Motif GL widget. Similar code can be used to create the Xt version. GLXconfig structure in GL: -------------------- The first step in creating a mixed-model widget is creating a GLXconfig structure describing the type of GL window you need. This structure should describe the normal window and any overlay, underlay or popup windows that will be required. NOTE: When requesting both double and single buffering, you MUST request a single buffered window in the GLXconfig structure. Since the double buffered window will be a child of the single buffered window, it is important that the parent have more bitplanes than the child. Here is an example of defining a GLXconfig structure for GL: static GLXconfig glxConfig [] = { { GLX_NORMAL, GLX_DOUBLE, FALSE }, { GLX_NORMAL, GLX_RGB, FALSE }, { GLX_OVERLAY, GLX_BUFSIZE, 2 }, { 0, 0, 0 } }; This GLXconfig structure requests a single buffered window, running in colormap mode with an overlay window having a depth of 2. GLXconfig in OpenGL: ------------------ For OpenGL you should specify and attribute lists like these: static int glxConfig[] = { GLX_RGBA, GLX_RED_SIZE,3, GLX_BLUE_SIZE,3, GLX_GREEN_SIZE,3, GLX_DEPTH_SIZE,12, None, }; static int glxConfigOverlay[] = { GLX_LEVEL, 1, GLX_BUFFER_SIZE, 4, None }; These are documented in the man page for glXChooseVisual. glxConfigOverlay is required if you want an overlay window. If its not specified you wont get an overlay window. Setting resources in GL: ------------------ The following code excerpt shows how to request a GLX widget that is single buffered (default window), colormapped and has overlay planes. It also enables the double buffered window. It assumes the GLXconfig structure shown above. n = 0; XtSetArg (args[n], GlxNglxConfig, glxConfig); n++; XtSetArg (args[n], GlxNuseOverlay, TRUE); n++; XtSetArg (args[n], GlxNprovideSingleBuffer, TRUE); n++; glw = XtCreateManagedWidget("glwidget", glxMDrawWidgetClass, frame, args, n); The first resource defines the GLXconfig structure to use. The second resource requests the overlay planes. The third resource indicates we also want the double buffered window. Setting resources in OpenGL: ------------------ For OpenGL the procedure is similar but slightly different. XtSetArg(args[n], GlxNglxConfig, glxConfig); n++; XtSetArg(args[n], GlxNoverlayGlxConfig, glxConfigOverlay); n++; glw = XtCreateManagedWidget("glwidget", glxMDrawWidgetClass, frame, args, n); The main difference here is that GlxNuseOverlay is no longer used. You need to specify an attribute list for the overlay buffer. If an attribute list is specified an overlay buffer will be provided. If there is no attribute list there will be no overlay. Switching single/double buffering: ---------------------------------- To switch to double buffer mode: n = 0; XtSetArg (args[n], GlxNsingleBuffer, FALSE); n++; XtSetValues (w, args, n); To switch to single buffer mode: n = 0; XtSetArg (args[n], GlxNsingleBuffer, TRUE); n++; XtSetValues (w, args, n); DEMO PROGRAM USAGE ------------------ The program overlay.c is a modification of the program overlay.c provided in 4Dgifts. If the symbol USE_NEW_WIDGET is not defined, it should work exactly like overlay.c. With the symbol defined, the mouse buttons work as follows: Left - Move the car in the main window Middle - Selects single buffering Right - Selects double buffering The house is in the overlay planes. The car is drawn in the normal planes and will flicker in single buffer mode. MORE WORK REQUIRED ------------------ When switching from one buffering mode to the other, much of the GL context set up in the old window is saved and restored into the new window. (Lighting, materials and textures must be done by the application.) It would be nice to be able to have a resource that indicates when this operation must be done so it isn't done every time. When switching from one buffering mode to the other OpenGL only these part sof the context are copied between the old and new context: GL_MODELVIEW Matrix GL_PROJECTION Matrix GL_VIEWPORT This is considerable less info between copied in the GL version of the widget. Feedback is desired on what should and shouldn't be copied between contexts when switching. Or you can easily change the stuff you want to copy by modifing SetNewWindow in GlxDraw.c. If an overlay is present these are copied between the Overlay contexts also. You will be in GL_MODELVIEW after a switch BUGS ---- None known at this time. CAUTIONS -------- Resize ------ At present I'm generating a resize callback for each set of windows so that the app can resize the viewport, for instance. However you won't get an expose/redraw on the inactive window. Two window implementation ------------------------- This implementation uses two different windows for single and double buffering. If auxiliary windows are used (i.e. overlays, popups) they will also be duplicated, with a set parented off the double buffer window and another set off the single buffer window. When a buffering mode switch occurs the core X window in the widget is swapped. This is done so that event handlers transparently switch to the new GL window. The only way to get around this switch is to figure out a portable way to switch buffering modes within one window which hasn't worked out yet. This core window switch may cause problems in the following areas: 1. If you get and save the core X window and try to use it when it is not active. Using XtWindow will always return the correct core window and is highly recommended. 2. This implementation hasn't been tested with X children attached to the GLX widget. I don't think this is common practice since windows are usually parented off of the window above the GLX widget. When time permits I will work on reparenting children so this will work. Colormaps --------- The resource GlxNoverrideColormap controls the behavior of installing colormaps at instantiation time. It is rather confusing how it works, though it works the same for this widget as for the standard GlxDraw and GlxMDraw widgets. By default GlxNoverrideColormap is set to TRUE. This means that the colormap provided in the GLXconfig structure (returned when the widget calls GLXgetconfig) will override the default colormap (which is usually from the parent). If the application wants to provide its own colormap at instantiation time, it must set XtNcolormap to this colormap and set GlxNoverrideColormap to FALSE. When creating the single and double buffered widget, the application must also set the colormap for GlxNaltColormap, which will be used for the secondary window. HINTS: If the application wants to use their own colormaps, it is usually desireable to find out what visuals will be assigned when the widget is realized. The application can find this out by calling GLXgetconfig itself. GLXgetconfig does nothing but build a table which is returned to the application with all the values filled in, rather than just the ones specified by the application. This table can be scanned for buffer=GLX_NORMAL and mode=GLX_COLORMAP to find out the colormap that will be assigned and buffer=GLX_NORMAL and mode=GLX_VISUAL to find out the visual that will be assigned. By changing the value of buffer=GLX_NORMAL and mode=GLX_DOUBLE, the same information can be determined for the secondary window. NEW RESOURCES ------------- The following lists and describes the new resources provided with this new version of the GLX widget: GlxNprovideSingleBuffer Class = GlxCProvideSingleBuffer Type = XtRBoolean This resource is used only on instantiation of the widget. It indicates whether both a double buffered and single buffered window are required. WARNING: If set to TRUE, be sure that the GLXconfig structure requests a single buffered window. Also, see the description for GlxNaltColormap below. GlxNmainWindow Class = GlxCWindow Type = XtRWindow This resource is filled with the window ID of the primary window. GlxNsingleBuffer Class = GlxCSingleBuffer Type = XtRBoolean This resource identifies which window is currently mapped. If TRUE, the single buffered window is mapped. It is also used to set which window is to be mapped, using XtSetValues. GlxNaltColormap Class = GlxCColormap Type = XtRColormap This resource contains the colormap of the secondary window. After instantiating the widget, it will be filled with the colormap. If the application wants to set the colormap for the secondary window, this needs to be set to the colormap ID for the secondary window. WARNING: To have this entry paid attention to, the resource GlxNoverrideColormap must be set to FALSE (default is TRUE). If this is done, the core colormap (XtNcolormap) must also be set with a colormap for the primary window.
Source
Documentation
Reference